#include <pthread.h>
#include <iostream>
#include <vector>
#include <unistd.h>
#include "lock.hpp"
using namespace std;

#define SUM 4
int ticket = 100;

struct description
{
    pthread_t pid;
    string name;
};

// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

// void* GrabTickets(void* variable)
// {
//     //sleep(1);
//     description* p = static_cast<description*>(variable);
//     cout << "我是" <<  p->name <<  ", pid: " << p->pid << endl;

//     //两种解锁方式都不行
//     //pthread_mutex_lock(&mutex);
//     // while(ticket > 0)
//     // {
//     //     usleep(1000);
//     //     cout << "我是" << p->name << ": ";
//     //     int tmp = ticket--;
//     //     cout << tmp << '\n';
//     //     //pthread_mutex_unlock(&mutex);
//     // }
//     //pthread_mutex_unlock(&mutex);

//     while(1)
//     {
//         pthread_mutex_lock(&mutex);
//         if(ticket > 0)
//         {
//             usleep(1000);
//             cout << "我是" << p->name << ": " << ticket-- << '\n';
//             pthread_mutex_unlock(&mutex);
//             usleep(10);
//         }
//         else
//         {
//             pthread_mutex_unlock(&mutex);
//             break;
//         }
//     }

//     printf("%s ... quit\n", p->name.c_str());
//     return nullptr;
// }

// int main()
// {
//     vector<description*> v(SUM);
//     for(int i = 0; i < SUM; ++i)
//     {
//         //注：不能在栈上建立个对象，一轮循环后对象就析构了
//         //并且for循环可能跑的很快，一下就干到SUM了
//         //要在堆上new一个对象出来
//         description p;
//         pthread_create(&(p.pid), nullptr, GrabTickets, &p);
//         p.name = "pthread-" + to_string(i + 1);
//         v[i] = &p;
//         cout << "创建线程: " << p.name << endl;
//     }

//     for(int i = 0; i < SUM; ++i)
//     {
//         pthread_join(v[i]->pid, nullptr);
//         delete v[i];
//     }
//     return 0;
// }

// int main()
// {
//     vector<description*> v(SUM);

//     for(int i = 0; i < SUM; ++i)
//     {
//         //sleep(1);
//         description* p = new description();
//         pthread_create(&(p->pid), nullptr, GrabTickets, p);
//         p->name = "pthread-" + to_string(i + 1);
//         v[i] = p;
//         cout << "创建线程: " << p->name << endl;
//     }

//     for(int i = 0; i < SUM; ++i)
//     {
//         pthread_join(v[i]->pid, nullptr);
//         delete v[i];
//     }
//     return 0;
// }

pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER;

void *GrabTickets(void *variable)
{
    description *p = static_cast<description *>(variable);
    cout << "我是" << p->name << ", pid: " << p->pid << endl;

    while (1)
    {
        {
            Mutex mutex(&mutex_);
            if (ticket > 0)
            {
                usleep(1000);
                cout << "我是" << p->name << ": " << ticket-- << '\n';
            }
            else
                break;
        }
        usleep(10);
    }

    printf("%s ... quit\n", p->name.c_str());
    return nullptr;
}

int main()
{
    vector<description *> v(SUM);

    for (int i = 0; i < SUM; ++i)
    {
        // sleep(1);
        description *p = new description();
        pthread_create(&(p->pid), nullptr, GrabTickets, p);
        p->name = "pthread-" + to_string(i + 1);
        v[i] = p;
        cout << "创建线程: " << p->name << endl;
    }

    for (int i = 0; i < SUM; ++i)
    {
        pthread_join(v[i]->pid, nullptr);
        delete v[i];
    }
    return 0;
}
